#ifndef GAMECONTROL_H
#define GAMECONTROL_H

#include <QObject>
#include "robot.h"
#include "userplayer.h"
#include "cards.h"

struct BetRecord
{
    BetRecord()
    {
        reset();
    }

    void reset()
    {
        player = nullptr;
        bet = 0;
        times = 0;
    }

    Player* player;
    int bet;
    int times;  // 判断第几次叫地主
};

class GameControl : public QObject
{
    Q_OBJECT
public:
    // 游戏状态
    enum GameStatus
    {
        DispatchCard,   // 发牌阶段
        CallingLord,    // 叫地主阶段
        PlayingHand,    // 出牌阶段
    };

    // 玩家状态
    enum PlayerStatus
    {
        ThinkingForCallLord,    // 考虑是否叫地主状态
        ThinkingForPlayHand,    // 考虑是否出牌状态
        Winning,                // 玩家赢的状态
    };


    explicit GameControl(QObject *parent = nullptr);


    // 初始化玩家
    void playerInit();

    // 得到玩家的实例对象
    Robot* getLeftRobot() const;
    Robot* getRightRobot() const;
    UserPlayer* getUserPlayer() const;

    // 设置当前玩家
    void setCurrentPlayer(Player* player);
    // 获取当前玩家
    Player* getCurrentPlayer() const;


    // 得到已出牌玩家
    Player* getPendPlayer() const;
    // 得到当前轮次所出的扑克牌
    Cards getPendCards() const;


    // 初始化扑克牌
    void initAllCards();
    // 每次发一张牌
    Card takeOneCard();
    // 得到叫地主的最后三张底牌
    Cards getSurplusCards() const;
    // 重置卡牌数据
    void resetCardsData();

    // 准备叫地主
    void startLordCard();
    // 成为地主
    void becomeLord(Player* player, int bet);
    // 清空所有玩家的得分
    void clearPlayerScore();
    // 得到玩家下注的最高分数
    int getPlayerMaxBet() const;

    // 处理叫地主的信号
    void onGrabet(Player* player, int bet);
    // 处理出牌
    void onPlayHand(Player* player, const Cards& cards);

signals:
    void playerStatusChanged(Player* player, PlayerStatus status);      // 通知主窗口玩家的状态发生变化的信号
    void notifyPlayerGrabLordBet(Player* player, int bet, bool flag);  // 通知玩家抢地主 flag用于标记第一个抢地主的人
                                                                       // flag为true表示第一个抢地主的玩家

    void gameStatusChanged(GameStatus status);                         // 游戏状态变化
    void notifyPlayHand(Player* player, const Cards& cards);                 // 通知玩家该出牌了
    void pendingInfo(Player* player, const Cards& cards);                    // 传递玩家出牌的信息（谁出的什么牌）

private:
    Robot* m_robotLeft = nullptr;     // 左边的机器人玩家
    Robot* m_robotRight = nullptr;    // 右边的机器人玩家
    UserPlayer* m_user = nullptr;     // 用户玩家
    Player* m_curPlayer = nullptr;    // 指向当前玩家
    Player* m_pendPlayer = nullptr;   // 指向已出牌的玩家
    Cards m_pendCards;      // 保存当前所打出的扑克牌
    Cards m_allCards;       // 本轮游戏所有的扑克牌
    BetRecord m_betRecord;  // 记录叫地主时玩家对应的信息
    int m_curBet = 0;           // 记录当前下注的分数
};

#endif // GAMECONTROL_H
